import pygame
import easygui
import random
import math
import time

# 初始化 Pygame
pygame.init()

# 设置游戏窗口
WIDTH, HEIGHT = 800, 600
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("简单 2D 游戏")

# 颜色定义
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
BROWN = (139, 69, 19)
ORANGE = (255, 165, 0)
BLACK = (0, 0, 0)
NIGHT_BLUE = (25, 25, 112)
GRAY = (128, 128, 128)
DARK_BROWN = (101, 67, 33)

# 玩家持有的物品，键为物品名，值为数量
bag = {
    "金条": 2,
    "银条": 6
}
# 商品信息，键为商品名，值为 (价格, 描述)
items = {
    "手枪": (50, "一把手枪"),
    "螺栓行动步枪": (125, "一把强力的螺栓行动步枪"),
    "绷带": (20, "用于治疗伤口的绷带"),
    "汉堡": (40, "美味的汉堡，补充能量"),
    "鸡腿": (50, "香嫩的鸡腿，恢复体力"),
    "菠菜罐头": (75, "富含营养的菠菜罐头"),
    "手枪子弹（24颗）": (15, "24 颗手枪子弹"),
    "步枪子弹（24颗）": (15, "24 颗步枪子弹")
}

# 回收物品信息，键为物品名，值为回收价格
recycle_items = {
    "金条": 50,
    "银条": 25
}

# 僵尸类
class Zombie:
    def __init__(self, player_x, player_y):
        # 在离玩家 30 米外随机生成僵尸
        angle = random.uniform(0, 2 * math.pi)
        self.x = player_x + 300 * random.uniform(1, 2) * math.cos(angle)
        self.y = player_y + 300 * random.uniform(1, 2) * math.sin(angle)
        self.width = 30
        self.height = 30
        self.vel = random.uniform(1, 3)  # 僵尸速度有快有慢
        self.variant = random.choice([0, 1])  # 0 普通僵尸，1 变种僵尸
        if self.variant == 1:
            self.width = 40
            self.height = 40
            self.vel *= 1.5  # 变种僵尸更快
        self.last_attack_time = 0
        self.health = 20  # 僵尸初始血量

    def move_towards_player(self, player_x, player_y, floor_y):
        dx = player_x - self.x
        dy = player_y - self.y
        distance = math.sqrt(dx ** 2 + dy ** 2)
        if distance > 0:
            self.x += self.vel * dx / distance
            self.y = floor_y - self.height  # 僵尸与地面平行

    def draw(self, win, offset_x, offset_y):
        if self.variant == 0:
            pygame.draw.rect(win, RED, (self.x - offset_x, self.y - offset_y, self.width, self.height))
        else:
            pygame.draw.rect(win, GRAY, (self.x - offset_x, self.y - offset_y, self.width, self.height))
        # 绘制僵尸血条
        pygame.draw.rect(win, RED, (self.x - offset_x, self.y - offset_y - 10, self.width, 5))
        pygame.draw.rect(win, GREEN, (self.x - offset_x, self.y - offset_y - 10, self.width * (self.health / 20), 5))

    def attack(self, target):
        current_time = time.time()
        if current_time - self.last_attack_time >= 0.5:
            target.health -= 10
            self.last_attack_time = current_time

    def is_dead(self):
        return self.health <= 0

# 玩家类
class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 50
        self.height = 50
        self.vel = 5
        self.is_jump = False
        self.jump_count = 10
        self.health = 100
        self.gold = 50  # 初始资金
        self.bullets = 0
        self.has_gun = False
        self.has_rifle = False
        self.shot_count = 0  # 记录射击次数
        self.pistol_shots = 0
        self.rifle_shots = 0
        self.distance_traveled = 0  # 记录玩家行走的距离
        self.last_x = x  # 记录玩家上一帧的 x 坐标

    def draw(self, win, offset_x, offset_y):
        pygame.draw.rect(win, WHITE, (self.x - offset_x, self.y - offset_y, self.width, self.height))
        # 绘制血条
        pygame.draw.rect(win, RED, (self.x - offset_x, self.y - offset_y - 10, self.width, 5))
        pygame.draw.rect(win, GREEN, (self.x - offset_x, self.y - offset_y - 10, self.width * (self.health / 100), 5))
        # 显示金币数
        font = pygame.font.Font(None, 36)
        text = font.render(f"金币: {self.gold}", True, WHITE)
        win.blit(text, (10, 10))
        # 显示玩家行走的距离
        distance_text = font.render(f"行走距离: {self.distance_traveled} 米", True, WHITE)
        win.blit(distance_text, (WIDTH - distance_text.get_width() - 10, 10))

    def move(self, keys, floor_y):
        dx = 0
        if keys[pygame.K_a]:
            dx -= self.vel
        if keys[pygame.K_d]:
            dx += self.vel
        if not self.is_jump:
            if keys[pygame.K_SPACE]:
                self.is_jump = True
        else:
            if self.jump_count >= -10:
                neg = 1
                if self.jump_count < 0:
                    neg = -1
                dy = (self.jump_count ** 2) * 0.5 * neg
                new_y = self.y - dy
                if new_y < floor_y - self.height:
                    self.y = new_y
                else:
                    self.y = floor_y - self.height
                    self.is_jump = False
                    self.jump_count = 10
                self.jump_count -= 1
            else:
                self.is_jump = False
                self.jump_count = 10
        self.x += dx
        # 计算玩家行走的距离
        self.distance_traveled += abs(dx)
        self.last_x = self.x

    def use_item(self, item_name):
        if item_name == "绷带" and self.health < 100:
            self.health = min(100, self.health + 20)
            bag["绷带"] -= 1
            easygui.msgbox("你使用了绷带，生命值恢复到 {}。".format(self.health), "使用物品")
        elif item_name == "汉堡":
            # 这里可以添加补充能量的逻辑
            bag["汉堡"] -= 1
            easygui.msgbox("你吃了汉堡，能量满满！", "使用物品")
        elif item_name == "鸡腿":
            # 这里可以添加恢复体力的逻辑
            bag["鸡腿"] -= 1
            easygui.msgbox("你吃了鸡腿，体力恢复！", "使用物品")
        elif item_name == "菠菜罐头":
            # 这里可以添加补充营养的逻辑
            bag["菠菜罐头"] -= 1
            easygui.msgbox("你吃了菠菜罐头，富含营养！", "使用物品")
        elif item_name == "手枪":
            self.has_gun = True
            easygui.msgbox("你装备了手枪！", "使用物品")
        elif item_name == "手枪子弹（24颗）":
            self.bullets += 24
            bag["手枪子弹（24颗）"] -= 1
            easygui.msgbox("你补充了 24 颗手枪子弹，当前子弹数：{}。".format(self.bullets), "使用物品")
        elif item_name == "螺栓行动步枪":
            self.has_rifle = True
            easygui.msgbox("你装备了螺栓行动步枪！", "使用物品")
        elif item_name == "步枪子弹（24颗）":
            self.bullets += 24
            bag["步枪子弹（24颗）"] -= 1
            easygui.msgbox("你补充了 24 颗步枪子弹！", "使用物品")

    def shoot(self, zombies):
        if (self.has_gun or self.has_rifle) and self.bullets > 0 and self.shot_count < 6:
            self.bullets -= 1
            self.shot_count += 1
            for zombie in zombies[:]:
                if self.has_gun:
                    zombie.health -= 7  # 手枪 3 枪一个
                    self.pistol_shots += 1
                    if zombie.is_dead():
                        zombies.remove(zombie)
                        self.pistol_shots = 0
                elif self.has_rifle:
                    zombie.health -= 20  # 步枪一枪一个
                    self.rifle_shots += 1
                    if zombie.is_dead():
                        zombies.remove(zombie)
                        self.rifle_shots = 0
            print("你开了一枪，剩余子弹数：{}。".format(self.bullets), "开枪")
        elif self.shot_count >= 6:
            self.shot_count = 0
            easygui.msgbox("换弹完成！", "换弹")

    def is_dead(self):
        return self.health <= 0

# 建筑类
class Building:
    def __init__(self, x, floor_y):
        self.x = x
        self.y = floor_y - 100
        self.width = 100
        self.height = 100
        self.has_item = random.choice([True, False])
        if self.has_item:
            self.item = random.choice(["金条", "银条"])
        self.type = random.randint(0, 4)  # 增加建筑类型

    def draw(self, win, offset_x, offset_y):
        if self.type == 0:
            # 普通建筑
            pygame.draw.rect(win, DARK_BROWN, (self.x - offset_x, self.y - offset_y, self.width, self.height))
            pygame.draw.rect(win, BROWN, (self.x - offset_x + 20, self.y - offset_y + 50, 20, 50))  # 门
            pygame.draw.rect(win, BLUE, (self.x - offset_x + 60, self.y - offset_y + 20, 20, 20))  # 窗户
        elif self.type == 1:
            # 仓库
            pygame.draw.rect(win, GRAY, (self.x - offset_x, self.y - offset_y, self.width, self.height))
            pygame.draw.rect(win, BLACK, (self.x - offset_x + 20, self.y - offset_y + 50, 60, 50))  # 大门
        elif self.type == 2:
            # 瞭望塔
            tower_width = 60
            tower_height = 150
            pygame.draw.rect(win, BROWN, (self.x - offset_x + (self.width - tower_width) // 2, self.y - offset_y - tower_height + self.height, tower_width, tower_height))
            pygame.draw.rect(win, BLUE, (self.x - offset_x + (self.width - 20) // 2, self.y - offset_y - 20 + self.height, 20, 20))  # 窗户
        elif self.type == 3:
            # 小木屋
            pygame.draw.rect(win, DARK_BROWN, (self.x - offset_x, self.y - offset_y, 80, 80))
            pygame.draw.rect(win, BROWN, (self.x - offset_x + 30, self.y - offset_y + 40, 20, 40))  # 门
            pygame.draw.rect(win, BLUE, (self.x - offset_x + 60, self.y - offset_y + 20, 10, 10))  # 窗户
        elif self.type == 4:
            # 废弃工厂
            pygame.draw.rect(win, GRAY, (self.x - offset_x, self.y - offset_y, 120, 120))
            pygame.draw.rect(win, BLACK, (self.x - offset_x + 40, self.y - offset_y + 80, 40, 40))  # 大门
            pygame.draw.rect(win, BLUE, (self.x - offset_x + 20, self.y - offset_y + 20, 20, 20))  # 窗户
            pygame.draw.rect(win, BLUE, (self.x - offset_x + 80, self.y - offset_y + 20, 20, 20))  # 窗户

    def check_collect(self, player):
        if (player.x < self.x + self.width and
            player.x + player.width > self.x and
            player.y < self.y + self.height and
            player.y + player.height > self.y):
            if self.has_item:
                bag[self.item] += 1
                self.has_item = False
                easygui.msgbox(f"你在建筑中找到了一个{self.item}！", "发现物品")

# 子弹类
class Bullet:
    def __init__(self, x, y, vel):
        self.x = x
        self.y = y
        self.vel = vel

    def move(self):
        self.x += self.vel

    def draw(self, win, offset_x, offset_y):
        pygame.draw.rect(win, YELLOW, (self.x - offset_x, self.y - offset_y, 5, 2))

# 士兵类
class Soldier:
    def __init__(self, x, floor_y):
        self.x = x
        self.y = floor_y - 50
        self.width = 30
        self.height = 50
        self.health = 100
        self.bullets = 100
        self.shot_count = 0
        self.bullets_list = []
        self.vel = 2  # 士兵移动速度
        self.move_direction = random.choice([-1, 1])  # 1 向右，-1 向左
        self.checkpoint_x = x  # 记录所属检查站的 x 坐标
        self.move_range = 50  # 移动范围
        self.zombie_in_sight = None
        self.last_shot_time = 0  # 记录士兵上次射击的时间

    def move(self):
        if self.zombie_in_sight is None:
            # 漫无目的游荡
            new_x = self.x + self.vel * self.move_direction
            if abs(new_x - self.checkpoint_x) > self.move_range:
                self.move_direction *= -1
            self.x += self.vel * self.move_direction
        else:
            # 朝向僵尸移动
            dx = self.zombie_in_sight.x - self.x
            distance = math.sqrt(dx ** 2)
            if distance > 0:
                self.x += self.vel * dx / distance

    def draw(self, win, offset_x, offset_y):
        # 绘制更精致的士兵
        pygame.draw.rect(win, BLUE, (self.x - offset_x, self.y - offset_y, self.width, self.height))
        pygame.draw.rect(win, BLACK, (self.x - offset_x + 5, self.y - offset_y, 20, 10))  # 头盔
        # 绘制血条
        pygame.draw.rect(win, RED, (self.x - offset_x, self.y - offset_y - 10, self.width, 5))
        pygame.draw.rect(win, GREEN, (self.x - offset_x, self.y - offset_y - 10, self.width * (self.health / 100), 5))
        for bullet in self.bullets_list:
            bullet.draw(win, offset_x, offset_y)

    def shoot(self, zombies):
        self.zombie_in_sight = None
        for zombie in zombies:
            dx = zombie.x - self.x
            distance = math.sqrt(dx ** 2)
            if distance < 200:
                self.zombie_in_sight = zombie
                break

        current_time = time.time()
        if self.zombie_in_sight and self.bullets > 0 and self.shot_count < 6 and current_time - self.last_shot_time >= 1:  # 限制射击间隔为 1 秒
            bullet = Bullet(self.x + self.width, self.y + self.height // 2, 10)
            self.bullets_list.append(bullet)
            self.bullets -= 1
            self.shot_count += 1
            self.last_shot_time = current_time
            for bullet in self.bullets_list[:]:
                bullet.move()
                if (bullet.x < self.zombie_in_sight.x + self.zombie_in_sight.width and
                    bullet.x + 5 > self.zombie_in_sight.x and
                    bullet.y < self.zombie_in_sight.y + self.zombie_in_sight.height and
                    bullet.y + 2 > self.zombie_in_sight.y):
                    self.zombie_in_sight.health -= 10  # 士兵两枪一个僵尸
                    if self.zombie_in_sight.is_dead():
                        zombies.remove(self.zombie_in_sight)
                        self.zombie_in_sight = None
                    self.bullets_list.remove(bullet)
                    break
        elif self.shot_count >= 6:
            self.shot_count = 0

# 检查站类（城堡）
class Checkpoint:
    def __init__(self, x, floor_y):
        self.x = x
        self.y = floor_y - 200
        self.width = 300
        self.height = 200
        self.soldiers = [Soldier(x + i * 60, floor_y) for i in range(3)]

    def draw(self, win, offset_x, offset_y):
        # 绘制更精致的城堡
        pygame.draw.rect(win, BROWN, (self.x - offset_x, self.y - offset_y, self.width, self.height))
        # 绘制塔楼
        tower_width = 50
        tower_height = 250
        pygame.draw.rect(win, BROWN, (self.x - offset_x, self.y - offset_y - 50, tower_width, tower_height))
        pygame.draw.rect(win, BROWN, (self.x - offset_x + self.width - tower_width, self.y - offset_y - 50, tower_width, tower_height))
        for soldier in self.soldiers:
            soldier.draw(win, offset_x, offset_y)

    def is_player_inside(self, player):
        player_left = player.x
        player_right = player.x + player.width
        player_top = player.y
        player_bottom = player.y + player.height

        checkpoint_left = self.x
        checkpoint_right = self.x + self.width
        checkpoint_top = self.y
        checkpoint_bottom = self.y + self.height

        return (
            player_left < checkpoint_right and
            player_right > checkpoint_left and
            player_top < checkpoint_bottom and
            player_bottom > checkpoint_top
        )

    def soldiers_shoot(self, zombies):
        for soldier in self.soldiers:
            soldier.shoot(zombies)

    def zombies_attack_soldiers(self, zombies):
        for zombie in zombies:
            for soldier in self.soldiers:
                if (zombie.x < soldier.x + soldier.width and
                    zombie.x + zombie.width > soldier.x and
                    zombie.y < soldier.y + soldier.height and
                    zombie.y + zombie.height > soldier.y):
                    zombie.attack(soldier)

    def update_soldiers(self):
        for soldier in self.soldiers:
            soldier.move()

# 创建玩家对象，出生在第一个检查站里
first_checkpoint_x = 100
player = Player(first_checkpoint_x + 150, 500 - 50)  # 调整玩家初始位置，使其站在地板上且在检查站里

# 绘制商店按钮
font = pygame.font.Font(None, 36)
shop_text = font.render("商店", True, ORANGE)  # 修改按钮文字颜色为橙色
shop_rect = shop_text.get_rect(topleft=(10, 50))

# 初始化僵尸列表
zombies = [Zombie(player.x, player.y) for _ in range(5)]

# 初始化建筑列表，减少建筑数量
buildings = [Building(1000 * i, 500) for i in range(1, 3)]

# 初始化检查站列表
checkpoints = [Checkpoint(1000 * i, 500) for i in range(1, 10)]

# 昼夜更替相关
day_time = True
day_counter = 0
DAY_LENGTH = 600  # 白天持续帧数
NIGHT_LENGTH = 300  # 夜晚持续帧数

def draw_background(win, offset_x, offset_y, is_day):
    if is_day:
        win.fill(BLUE)
        # 绘制太阳
        pygame.draw.circle(win, YELLOW, (100 - offset_x % WIDTH, 100 - offset_y % HEIGHT), 50)
    else:
        win.fill(NIGHT_BLUE)
        # 绘制月亮
        pygame.draw.circle(win, WHITE, (100 - offset_x % WIDTH, 100 - offset_y % HEIGHT), 30)
    # 绘制树木，树有高有低
    for i in range(10):
        tree_x = i * 200 - offset_x % 2000
        tree_y = 400 - offset_y % 1000
        tree_trunk_width = 30
        tree_trunk_height = 100
        tree_crown_radius = random.randint(50, 80)  # 树冠半径随机
        # 绘制树干
        pygame.draw.rect(win, BROWN, (tree_x, tree_y, tree_trunk_width, tree_trunk_height))
        # 绘制树冠
        pygame.draw.circle(win, GREEN, (tree_x + tree_trunk_width // 2, tree_y - tree_crown_radius + 50), tree_crown_radius)

def draw_floor(win, offset_y):
    # 绘制绿色地板
    floor_y = HEIGHT - 100
    pygame.draw.rect(win, GREEN, (0, floor_y - offset_y % 100, WIDTH, 100))
    return floor_y

def open_shop(player):
    money = player.gold
    while True:
        main_choice = easygui.choicebox("欢迎来到商店，你当前有 ${}。请选择操作：".format(money), "主菜单", ["进入商店", "进入回收系统", "退出"])
        if main_choice == "退出":
            easygui.msgbox("感谢光临，欢迎下次再来！", "退出系统")
            break
        elif main_choice is None:
            break
        elif main_choice == "进入商店":
            while True:
                # 显示商品列表
                item_list = []
                for item, (price, desc) in items.items():
                    item_list.append(f"{item} - ${price} - {desc}")
                item_list.append("返回主菜单")

                # Check if there are at least two choices
                if len(item_list) < 2:
                    easygui.msgbox("暂无商品可供购买。", "商店提示")
                    break

                choice = easygui.choicebox("欢迎来到商店，你当前有 ${}。请选择要购买的商品：".format(money), "商店系统", item_list)

                if choice == "返回主菜单":
                    break
                elif choice is None:
                    break
                else:
                    # 提取商品名
                    selected_item = choice.split(" - ")[0]
                    price = items[selected_item][0]
                    if money >= price:
                        money -= price
                        # 更新玩家物品数量
                        bag[selected_item] = bag.get(selected_item, 0) + 1
                        easygui.msgbox("你成功购买了 {}，剩余资金 ${}。".format(selected_item, money), "购买成功")
                    else:
                        easygui.msgbox("你的资金不足，无法购买 {}。".format(selected_item), "购买失败")
        elif main_choice == "进入回收系统":
            while True:
                # 显示可回收物品列表，仅显示玩家拥有的物品
                recycle_list = []
                for item, price in recycle_items.items():
                    if bag.get(item, 0) > 0:
                        recycle_list.append(f"{item} - 回收价: ${price}")
                recycle_list.append("返回主菜单")

                # Check if there are at least two choices
                if len(recycle_list) < 2:
                    easygui.msgbox("暂无物品可供回收。", "回收提示")
                    break

                recycle_choice = easygui.choicebox("欢迎来到回收系统，你当前有 {}$。请选择要回收的物品：".format(money), "回收系统", recycle_list)

                if recycle_choice == "返回主菜单":
                    break
                elif recycle_choice is None:
                    break
                else:
                    # 提取回收物品名
                    selected_recycle_item = recycle_choice.split(" - ")[0]
                    price = recycle_items[selected_recycle_item]
                    # 检查玩家是否拥有该物品
                    if bag[selected_recycle_item] > 0:
                        money += price
                        # 更新玩家物品数量
                        bag[selected_recycle_item] -= 1
                        easygui.msgbox("你成功回收了 {}，当前资金 ${}。".format(selected_recycle_item, money), "回收成功")
    player.gold = money

# 游戏主循环
clock = pygame.time.Clock()
run = True
while run:
    clock.tick(60)

    # 计算偏移量，以玩家为中心
    offset_x = player.x - WIDTH // 2
    offset_y = player.y - HEIGHT // 2

    # 昼夜更替逻辑
    day_counter += 1
    if day_time and day_counter >= DAY_LENGTH:
        day_time = False
        day_counter = 0
    elif not day_time and day_counter >= NIGHT_LENGTH:
        day_time = True
        day_counter = 0

    floor_y = draw_floor(win, offset_y)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键开枪
                player.shoot(zombies)
            elif shop_rect.collidepoint(event.pos):
                inside_checkpoint = False
                for checkpoint in checkpoints:
                    if checkpoint.is_player_inside(player):
                        inside_checkpoint = True
                        break
                if inside_checkpoint:
                    open_shop(player)
                else:
                    easygui.msgbox("只有在检查站才能打开商店！", "商店提示")
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_e:
                for building in buildings:
                    if (player.x < building.x + building.width and
                        player.x + player.width > building.x and
                        player.y < building.y + building.height and
                        player.y + player.height > building.y):
                        building.check_collect(player)
                        break
                for item in bag:
                    if bag[item] > 0:
                        use_choice = easygui.choicebox("你要使用哪个物品？", "使用物品", [item, "取消"])
                        if use_choice == item:
                            player.use_item(item)
                            break
            elif event.key == pygame.K_t:  # 按 T 键打开商店
                inside_checkpoint = False
                for checkpoint in checkpoints:
                    if checkpoint.is_player_inside(player):
                        inside_checkpoint = True
                        break
                if inside_checkpoint:
                    open_shop(player)
                else:
                    easygui.msgbox("只有在检查站才能打开商店！", "商店提示")

    keys = pygame.key.get_pressed()
    player.move(keys, floor_y)

    # 检查玩家是否在检查站里，在则绝对安全
    player_inside_checkpoint = False
    for checkpoint in checkpoints:
        if checkpoint.is_player_inside(player):
            player_inside_checkpoint = True
            break

    # 更新僵尸位置
    for zombie in zombies:
        zombie.move_towards_player(player.x, player.y, floor_y)
        if not player_inside_checkpoint:
            if (zombie.x < player.x + player.width and
                zombie.x + zombie.width > player.x and
                zombie.y < player.y + player.height and
                zombie.y + zombie.height > player.y):
                zombie.attack(player)

    # 夜晚无限刷新僵尸
    if not day_time and random.random() < 0.02:
        zombies.append(Zombie(player.x, player.y))

    # 检查玩家是否收集建筑中的物品
    for building in buildings:
        building.check_collect(player)

    # 士兵射击僵尸
    for checkpoint in checkpoints:
        checkpoint.soldiers_shoot(zombies)
        checkpoint.zombies_attack_soldiers(zombies)
        checkpoint.update_soldiers()

    # 检查玩家是否死亡
    if player.is_dead():
        easygui.msgbox("你已死亡，游戏结束！", "游戏结束")
        run = False

    # 检查玩家是否行走 5000 米通关
    if player.distance_traveled >= 10000:
        easygui.msgbox("你已经行走了 10000 米，游戏通关！", "游戏通关")
        run = False

    # 绘制背景
    draw_background(win, offset_x, offset_y, day_time)

    # 绘制建筑
    for building in buildings:
        building.draw(win, offset_x, offset_y)

    # 绘制检查站
    for checkpoint in checkpoints:
        checkpoint.draw(win, offset_x, offset_y)

    # 绘制商店按钮
    win.blit(shop_text, shop_rect)

    # 绘制玩家
    player.draw(win, offset_x, offset_y)

    # 绘制僵尸
    for zombie in zombies:
        zombie.draw(win, offset_x, offset_y)

    pygame.display.update()

pygame.quit()